package com.fengyunhe.common;

import com.fengyunhe.manager.AdminLog;
import com.fengyunhe.manager.service.AdminLogService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.web.servlet.ModelAndView;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * 功能：日志记录切面
 * 作者： yangyan
 * 时间： 2014/11/2 .
 */
public class LogAspect {

    @Autowired
    private AdminLogService adminLogService;
    Logger log = LoggerFactory.getLogger(LogAspect.class);
    SpelExpressionParser parser = new SpelExpressionParser();
    TemplateParserContext templateParserContext = new TemplateParserContext("#{", "}");

    public Object log(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object result = null;
        Throwable error = null;
        try {
            result = proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            error = throwable;
            throwable.printStackTrace();
            throw throwable;
        } finally {
            try {
                MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
                Method m = methodSignature.getMethod();
                Object[] args = proceedingJoinPoint.getArgs();
                String action = m.getAnnotation(AdminLog.class).action();
                StandardEvaluationContext context = new StandardEvaluationContext(new LogContext(args, result));
                String actionString = parser.parseExpression(action, templateParserContext).getValue(context, String.class);
                String module = m.getAnnotation(AdminLog.class).module();
                boolean success = false;
                String msg = null;
                if (result == null) {

                } else if (result instanceof Map) {
                    success = (Boolean) ((Map) result).get("success");
                    if (success) {
                        msg = (String) ((Map) result).get("msg");
                    } else {
                        msg = (String) ((Map) result).get("error");
                    }
                } else if (result instanceof ModelAndView) {
                    success = (Boolean) ((ModelAndView) result).getModel().get("success");
                    if (success) {
                        msg = (String) ((ModelAndView) result).getModel().get("msg");
                    } else {
                        msg = (String) ((ModelAndView) result).getModel().get("error");
                    }
                }

                if (msg == null && error != null) {
                    msg = error.getMessage();
                }
                adminLogService.addLog(actionString, module, success, args, msg);
            } catch (Exception e) {
                e.printStackTrace();
                log.error("日志记录出错", e);
            }
        }


        return result;
    }

    /**
     * 日志上下文
     */
    static class LogContext {

        public LogContext(Object[] args, Object result) {
            this.args = args;
            this.result = result;
        }

        private Object[] args;
        private Object result;


        public Object[] getArgs() {
            return args;
        }

        public void setArgs(Object[] args) {
            this.args = args;
        }

        public Object getResult() {
            return result;
        }

        public void setResult(Object result) {
            this.result = result;
        }
    }
}
